/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package edu.udlap.spring2008.is300.finalexam.app.mvc.view;

import edu.udlap.spring2008.is300.finalexam.app.mvc.model.database.filters.AppImageRecordFilterCategory;
import edu.udlap.spring2008.is300.finalexam.app.mvc.model.database.filters.AppImageRecordFilterDescription;
import edu.udlap.spring2008.is300.finalexam.app.mvc.model.database.filters.AppImageRecordFilterFavorite;
import edu.udlap.spring2008.is300.finalexam.app.mvc.model.database.filters.AppImageRecordFilterFormat;
import edu.udlap.spring2008.is300.finalexam.app.mvc.model.database.filters.AppImageRecordFilterNullFilter;
import edu.udlap.spring2008.is300.finalexam.app.mvc.model.database.filters.AppImageRecordFilterPrivacyLevel;
import edu.udlap.spring2008.is300.finalexam.app.mvc.model.database.filters.AppImageRecordFilterSize;
import edu.udlap.spring2008.is300.finalexam.framework.mvc.model.database.objects.CategoryRecord;
import edu.udlap.spring2008.is300.finalexam.framework.mvc.model.database.objects.FormatRecord;
import edu.udlap.spring2008.is300.finalexam.framework.mvc.model.ModelState;
import edu.udlap.spring2008.is300.finalexam.framework.mvc.model.database.filters.ImageRecordFilter;
import edu.udlap.spring2008.is300.finalexam.framework.mvc.model.database.objects.PrivacyLevelRecord;
import edu.udlap.spring2008.is300.finalexam.framework.mvc.model.database.objects.SizeRecord;
import edu.udlap.spring2008.is300.finalexam.framework.mvc.view.ViewComponent;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.BoxLayout;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;

/**
 *
 * @author LILIANA ROJAS
 */
public class ViewImageFilterControls extends ViewComponent implements
        ActionListener,
        DocumentListener
{

    protected JPanel contentPanel_ = new JPanel();
    protected JPanel comboBoxesPanel_ = new JPanel();
    protected JPanel otherControlsPanel_ = new JPanel();
    
    protected JCheckBox categoryCheckbox_ = new JCheckBox("Category:");
    protected JCheckBox sizeCheckbox_ = new JCheckBox("Size:");
    protected JCheckBox privacyLevelCheckbox_ = new JCheckBox("Privacy Level:");
    protected JCheckBox formatCheckbox_ = new JCheckBox("Format:");
    protected JCheckBox favoriteCheckbox_ = new JCheckBox("Favorite:");
    protected JCheckBox descriptionCheckbox_ = new JCheckBox("Description:");
    
    protected JCheckBox categoryNotCheckbox_ = new JCheckBox("not");
    protected JCheckBox sizeNotCheckbox_ = new JCheckBox("not");
    protected JCheckBox privacyLevelNotCheckbox_ = new JCheckBox("not");
    protected JCheckBox formatNotCheckbox_ = new JCheckBox("not");
    protected JCheckBox favoriteNotCheckbox_ = new JCheckBox("not");
    protected JCheckBox descriptionNotCheckbox_ = new JCheckBox("not");
    
    protected JComboBox categoryComboBox_ = new JComboBox();
    protected JComboBox sizeComboBox_ = new JComboBox();
    protected JComboBox privacyLevelComboBox_ = new JComboBox();
    protected JComboBox formatComboBox_ = new JComboBox();
    protected JCheckBox favoriteStatusCheckBox_ = new JCheckBox("Yes");
    protected JTextArea descriptionTextArea_ = new JTextArea();
    
    public ViewImageFilterControls()
    {
        initializeControls();
        initializeComboBoxesPanel();
        initializeOtherControlsPanel();
        initializeContentPanel();
    }

    protected void listenToControls()
    {
        ///add action listener...
        categoryCheckbox_.addActionListener(this);
        sizeCheckbox_.addActionListener(this);
        privacyLevelCheckbox_.addActionListener(this);
        formatCheckbox_.addActionListener(this);
        favoriteCheckbox_.addActionListener(this);
        descriptionCheckbox_.addActionListener(this);
        
        categoryNotCheckbox_.addActionListener(this);
        sizeNotCheckbox_.addActionListener(this);
        privacyLevelNotCheckbox_.addActionListener(this);
        formatNotCheckbox_.addActionListener(this);
        favoriteNotCheckbox_.addActionListener(this);
        descriptionNotCheckbox_.addActionListener(this);
        
        categoryComboBox_.addActionListener(this);
        sizeComboBox_.addActionListener(this);
        privacyLevelComboBox_.addActionListener(this);
        formatComboBox_.addActionListener(this);
        favoriteStatusCheckBox_.addActionListener(this);
        descriptionTextArea_.getDocument().addDocumentListener(this);
    }
    
    protected void stopListeningToControls()
    {
        ///add action listener...
        categoryCheckbox_.removeActionListener(this);
        sizeCheckbox_.removeActionListener(this);
        privacyLevelCheckbox_.removeActionListener(this);
        formatCheckbox_.removeActionListener(this);
        favoriteCheckbox_.removeActionListener(this);
        descriptionCheckbox_.removeActionListener(this);
        
        categoryNotCheckbox_.removeActionListener(this);
        sizeNotCheckbox_.removeActionListener(this);
        privacyLevelNotCheckbox_.removeActionListener(this);
        formatNotCheckbox_.removeActionListener(this);
        favoriteNotCheckbox_.removeActionListener(this);
        descriptionNotCheckbox_.removeActionListener(this);
        
        categoryComboBox_.removeActionListener(this);
        sizeComboBox_.removeActionListener(this);
        privacyLevelComboBox_.removeActionListener(this);
        formatComboBox_.removeActionListener(this);
        favoriteStatusCheckBox_.removeActionListener(this);
        descriptionTextArea_.getDocument().removeDocumentListener(this);
    }
    
    protected void initializeControls()
    {
        Dimension d;
     
        ///initialize descriptionTextArea_...
        d = new Dimension(300, 40);
        descriptionTextArea_.setMinimumSize(d);
        //descriptionTextArea_.setMaximumSize(d);
        descriptionTextArea_.setPreferredSize(d);
        descriptionTextArea_.setLineWrap(true);
        descriptionTextArea_.setWrapStyleWord(true);        
        
        //initialize favoriteCheckBox_...
        favoriteStatusCheckBox_.setAlignmentX(0);
        
        //initialize descriptionCheckbox_...
        descriptionCheckbox_.setAlignmentX(0);
        
        ///initialize descriptionTextArea_....
        descriptionTextArea_.setAlignmentX(0);
    }
    
    protected void initializeComboBoxesPanel()
    {
        ///create the combo
        GroupLayout layout = new GroupLayout(comboBoxesPanel_);
        
        comboBoxesPanel_.setLayout(layout);
        
        // Turn on automatically adding gaps between components
        layout.setAutoCreateGaps(true);

        // Turn on automatically creating gaps between components that touch
        // the edge of the container and the container.
        layout.setAutoCreateContainerGaps(true);

        // Create a sequential group for the horizontal axis.
        GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();

        // The sequential group in turn contains two parallel groups.
        // One parallel group contains the labels, the other the text fields.
        // Putting the labels in a parallel group along the horizontal axis
        // positions them at the same x location.
        //
        // Variable indentation is used to reinforce the level of grouping.
        hGroup.addGroup(layout.createParallelGroup().
                addComponent(categoryCheckbox_).
                addComponent(sizeCheckbox_).
                addComponent(privacyLevelCheckbox_).
                addComponent(formatCheckbox_).
                addComponent(favoriteCheckbox_)
                );
        hGroup.addGroup(layout.createParallelGroup().
                addComponent(categoryNotCheckbox_).
                addComponent(sizeNotCheckbox_).
                addComponent(privacyLevelNotCheckbox_).
                addComponent(formatNotCheckbox_).
                addComponent(favoriteNotCheckbox_)
                );
        hGroup.addGroup(layout.createParallelGroup().
                addComponent(categoryComboBox_).
                addComponent(sizeComboBox_).
                addComponent(privacyLevelComboBox_).
                addComponent(formatComboBox_).
                addComponent(favoriteStatusCheckBox_)
                );
        layout.setHorizontalGroup(hGroup);

        // Create a sequential group for the vertical axis.
        GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();

        // The sequential group contains two parallel groups that align
        // the contents along the baseline. The first parallel group contains
        // the first label and text field, and the second parallel group contains
        // the second label and text field. By using a sequential group
        // the labels and text fields are positioned vertically after one another.
        vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
                addComponent(categoryCheckbox_).
                addComponent(categoryNotCheckbox_).
                addComponent(categoryComboBox_)
                );
        vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
                addComponent(sizeCheckbox_).
                addComponent(sizeNotCheckbox_).
                addComponent(sizeComboBox_)
                );
        vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
                addComponent(privacyLevelCheckbox_).
                addComponent(privacyLevelNotCheckbox_).
                addComponent(privacyLevelComboBox_)
                );
        vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
                addComponent(formatCheckbox_).
                addComponent(formatNotCheckbox_).
                addComponent(formatComboBox_)
                );
        vGroup.addGroup(layout.createParallelGroup(Alignment.BASELINE).
                addComponent(favoriteCheckbox_).
                addComponent(favoriteNotCheckbox_).
                addComponent(favoriteStatusCheckBox_)
                );
        layout.setVerticalGroup(vGroup);
    }
    
    protected void initializeOtherControlsPanel()
    {
        otherControlsPanel_.setAlignmentX(0.5f);
        BoxLayout layout = new BoxLayout(otherControlsPanel_, BoxLayout.Y_AXIS);
        otherControlsPanel_.setLayout(layout);
        
        otherControlsPanel_.add(descriptionCheckbox_);
        otherControlsPanel_.add(descriptionTextArea_);
    }
    
    protected void initializeContentPanel()
    {   
        /*
        contentPanel_.setPreferredSize(new Dimension(300, 350));
        contentPanel_.setMinimumSize(new Dimension(200, 250));
        contentPanel_.setMaximumSize(new Dimension(400, 450));
        */
        
        BoxLayout layout = new BoxLayout(contentPanel_, BoxLayout.Y_AXIS);
        contentPanel_.setLayout(layout);
        
        contentPanel_.add(comboBoxesPanel_);
        contentPanel_.add(otherControlsPanel_);
        
        contentPanel_.repaint();
    }
    
    // <editor-fold desc="overriden & implemented operations...">
    @Override
    public void setInitialState(ModelState modelState)
    {
        ///update categories combobox items...
        {
            categoryComboBox_.removeAllItems();

            ArrayList<CategoryRecord> categoryRecords =
                    modelState.getCategoryRecords();

            Iterator<CategoryRecord> i = categoryRecords.iterator();
            CategoryRecord categoryRecord;
            while(i.hasNext())
            {
                categoryRecord = i.next();
                categoryComboBox_.addItem(categoryRecord);
            }
        }
        
        ///update size combobox items...
        {
            sizeComboBox_.removeAllItems();

            ArrayList<SizeRecord> sizeRecords =
                    modelState.getSizeRecords();

            Iterator<SizeRecord> i = sizeRecords.iterator();
            SizeRecord sizeRecord;
            while(i.hasNext())
            {
                sizeRecord = i.next();
                sizeComboBox_.addItem(sizeRecord);
            }
        }
        
        ///update privacy level combobox items...
        {
            privacyLevelComboBox_.removeAllItems();

            ArrayList<PrivacyLevelRecord> privacyLevelRecords =
                    modelState.getPrivacyLevelRecords();

            Iterator<PrivacyLevelRecord> i = privacyLevelRecords.iterator();
            PrivacyLevelRecord privacyLevelRecord;
            while(i.hasNext())
            {
                privacyLevelRecord = i.next();
                privacyLevelComboBox_.addItem(privacyLevelRecord);
            }
        }
        
        ///update format level combobox items...
        {
            formatComboBox_.removeAllItems();

            ArrayList<FormatRecord> formatRecords =
                    modelState.getFormatRecords();

            Iterator<FormatRecord> i = formatRecords.iterator();
            FormatRecord formatRecord;
            while(i.hasNext())
            {
                formatRecord = i.next();
                formatComboBox_.addItem(formatRecord);
            }
        }
        
        imageSetChanged(modelState);
        
        //listenToControls();
    }
    
    @Override
    public void imageSetChanged(ModelState modelState)
    {
        ///stop listening so that we don't generate any events here...
        stopListeningToControls();
        
        ///disable everything...
        categoryComboBox_.setEnabled(false);
        sizeComboBox_.setEnabled(false);
        privacyLevelComboBox_.setEnabled(false);
        formatComboBox_.setEnabled(false);
        favoriteStatusCheckBox_.setEnabled(false);
        if(!descriptionTextArea_.hasFocus())
            descriptionTextArea_.setEnabled(false);
        
        categoryNotCheckbox_.setEnabled(false);
        sizeNotCheckbox_.setEnabled(false);
        privacyLevelNotCheckbox_.setEnabled(false);
        formatNotCheckbox_.setEnabled(false);
        favoriteNotCheckbox_.setEnabled(false);
        descriptionNotCheckbox_.setEnabled(false);
        
        categoryNotCheckbox_.setSelected(false);
        sizeNotCheckbox_.setSelected(false);
        privacyLevelNotCheckbox_.setSelected(false);
        formatNotCheckbox_.setSelected(false);
        favoriteNotCheckbox_.setSelected(false);
        descriptionNotCheckbox_.setSelected(false);
        
        categoryCheckbox_.setSelected(false);
        sizeCheckbox_.setSelected(false);
        privacyLevelCheckbox_.setSelected(false);
        formatCheckbox_.setSelected(false);
        favoriteCheckbox_.setSelected(false);
        descriptionCheckbox_.setSelected(false);

        ///discover all applied filters...
        ImageRecordFilter imageRecordFilter = modelState.getImageRecordFilter();

        ArrayList<ImageRecordFilter> imageRecordFilters =
                imageRecordFilter.getAppliedImageRecordFilters();
                
        Iterator<ImageRecordFilter> i = imageRecordFilters.iterator();
        while(i.hasNext())
        {
            imageRecordFilter = i.next();
            
            if(imageRecordFilter instanceof
                    AppImageRecordFilterCategory)
            {
                categoryCheckbox_.setSelected(true);
                categoryComboBox_.setEnabled(true);
                categoryNotCheckbox_.setEnabled(true);
                categoryNotCheckbox_.setSelected(
                        imageRecordFilter.isNegated());
                categoryComboBox_.setSelectedItem(
                        (CategoryRecord)imageRecordFilter.getFilterValue());
                
            }
            else if(imageRecordFilter instanceof
                    AppImageRecordFilterSize)
            {
                sizeCheckbox_.setSelected(true);
                sizeComboBox_.setEnabled(true);
                sizeNotCheckbox_.setEnabled(true);
                sizeNotCheckbox_.setSelected(
                        imageRecordFilter.isNegated());
                sizeComboBox_.setSelectedItem(
                        (SizeRecord)imageRecordFilter.getFilterValue());
            }
            else if(imageRecordFilter instanceof
                    AppImageRecordFilterPrivacyLevel)
            {
                privacyLevelCheckbox_.setSelected(true);
                privacyLevelComboBox_.setEnabled(true);
                privacyLevelNotCheckbox_.setEnabled(true);
                privacyLevelNotCheckbox_.setSelected(
                        imageRecordFilter.isNegated());
                privacyLevelComboBox_.setSelectedItem(
                        (PrivacyLevelRecord)imageRecordFilter.getFilterValue());
            }
            else if(imageRecordFilter instanceof 
                    AppImageRecordFilterFormat)
            {
                formatCheckbox_.setSelected(true);
                formatComboBox_.setEnabled(true);
                formatNotCheckbox_.setEnabled(true);
                formatNotCheckbox_.setSelected(
                        imageRecordFilter.isNegated());
                formatComboBox_.setSelectedItem(
                        (FormatRecord)imageRecordFilter.getFilterValue());
            }
            else if(imageRecordFilter instanceof 
                    AppImageRecordFilterFavorite)
            {
                favoriteCheckbox_.setSelected(true);
                favoriteStatusCheckBox_.setEnabled(true);
                favoriteNotCheckbox_.setEnabled(true);
                favoriteNotCheckbox_.setSelected(
                        imageRecordFilter.isNegated());
                favoriteStatusCheckBox_.setSelected(
                        ((Boolean)imageRecordFilter.getFilterValue()).
                        booleanValue());
            }
            else if(imageRecordFilter instanceof 
                    AppImageRecordFilterDescription)
            {
                descriptionCheckbox_.setSelected(true);
                descriptionTextArea_.setEnabled(true);
                descriptionNotCheckbox_.setEnabled(true);
                descriptionNotCheckbox_.setSelected(
                        imageRecordFilter.isNegated());
                if(!descriptionTextArea_.hasFocus())
                    descriptionTextArea_.setText(
                        (String)imageRecordFilter.getFilterValue());
            }
        }
        
        ///listen again...
        listenToControls();
    }
    
    @Override
    public void selectionChanged(ModelState modelState)
    {   
        ///do nothing...
    }
    
    @Override
    public void favoritesChanged(ModelState modelState)
    {
        ///do nothing...
    }

    @Override
    public void slideShowMode()
    {
        ///do nothing...
    }

    @Override
    public void gridMode()
    {
        ///do nothing...
    }

    @Override
    public Component getComponent()
    {
        return (Component)contentPanel_;
    }

    public void actionPerformed(ActionEvent e)
    {
        if(controller_ == null)
            return;
        
        Object source = e.getSource();
        
        if(source == categoryCheckbox_)
        {
            setFilter();
            //categoryComboBox_.setEnabled(categoryCheckbox_.isSelected());
        }
        else if(source == sizeCheckbox_)
        {
            setFilter();
            //sizeComboBox_.setEnabled(sizeCheckbox_.isSelected());
        }
        else if(source == privacyLevelCheckbox_)
        {
            setFilter();
            //privacyLevelComboBox_.setEnabled(privacyLevelCheckbox_.
            //        isSelected());
        }
        else if(source == formatCheckbox_)
        {
            setFilter();
            //formatComboBox_.setEnabled(formatCheckbox_.isSelected());
        }
        else if(source == favoriteCheckbox_)
        {
            setFilter();
            //favoriteStatusCheckBox_.setEnabled(favoriteCheckbox_.
            //        isSelected());
        }
        else if(source == descriptionCheckbox_)
        {
            setFilter();
            //descriptionTextArea_.setEnabled(descriptionCheckbox_.isSelected());
        }
        else if(source == categoryNotCheckbox_)
        {
            setFilter();
        }
        else if(source == sizeNotCheckbox_)
        {
            setFilter();
        }
        else if(source == privacyLevelNotCheckbox_)
        {
            setFilter();
        }
        else if(source == formatNotCheckbox_)
        {
            setFilter();
        }
        else if(source == favoriteNotCheckbox_)
        {
            setFilter();
        }
        else if(source == descriptionNotCheckbox_)
        {
            setFilter();
        }
        else if(source == categoryComboBox_)
        {
            setFilter();
        }
        else if(source == sizeComboBox_)
        {
            setFilter();
        }
        else if(source == privacyLevelComboBox_)
        {
            setFilter();
        }
        else if(source == formatComboBox_)
        {
            setFilter();
        }
        else if(source == favoriteStatusCheckBox_)
        {
            setFilter();
        }

    }
    
    public void insertUpdate(DocumentEvent e)
    {
        if(controller_ == null)
            return;
        
        Document source = e.getDocument();
        
        if(source == descriptionTextArea_.getDocument())
        {
            setFilter();
        }
    }

    public void removeUpdate(DocumentEvent e)
    {
        insertUpdate(e);
    }

    public void changedUpdate(DocumentEvent e)
    {
        ///do nothing...
    }
    
    private void setFilter()
    {
        ImageRecordFilter imageFilter =
                new AppImageRecordFilterNullFilter();
        
        if(categoryCheckbox_.isSelected())
        {
            imageFilter = new AppImageRecordFilterCategory(
                    imageFilter, 
                    (CategoryRecord)categoryComboBox_.getSelectedItem(),
                    categoryNotCheckbox_.isSelected());
        }
        
        if(sizeCheckbox_.isSelected())
        {
            imageFilter = new AppImageRecordFilterSize(
                    imageFilter, 
                    (SizeRecord)sizeComboBox_.getSelectedItem(),
                    sizeNotCheckbox_.isSelected());
        }
        
        if(privacyLevelCheckbox_.isSelected())
        {
            imageFilter = new AppImageRecordFilterPrivacyLevel(
                    imageFilter, 
                    (PrivacyLevelRecord)privacyLevelComboBox_.getSelectedItem(),
                    privacyLevelNotCheckbox_.isSelected());
        }
        
        if(formatCheckbox_.isSelected())
        {
            imageFilter = new AppImageRecordFilterFormat(
                    imageFilter, 
                    (FormatRecord)formatComboBox_.getSelectedItem(),
                    formatNotCheckbox_.isSelected());
        }
        
        if(favoriteCheckbox_.isSelected())
        {
            imageFilter = new AppImageRecordFilterFavorite(
                    imageFilter, 
                    favoriteStatusCheckBox_.isSelected(),
                    favoriteNotCheckbox_.isSelected());
        }
        
        if(descriptionCheckbox_.isSelected())
        {
            imageFilter = new AppImageRecordFilterDescription(
                    imageFilter,
                    descriptionTextArea_.getText(),
                    descriptionNotCheckbox_.isSelected());
        }        
        
        if(controller_ != null)
            controller_.setImageRecordFilter(imageFilter);
    }
    // </editor-fold>
}
